package com.dg.gaming.client.gui {
    import com.dg.gaming.api.common.GameModel;
    import com.dg.gaming.api.common.Table;
    import com.dg.gaming.api.common.msg.Msg;
    import com.dg.gaming.api.common.msg.MsgConnectTable;
    import com.dg.gaming.api.common.msg.MsgError;
    import com.dg.gaming.api.common.msg.MsgTableConnect;
    import com.dg.gaming.api.common.util.DGLabels;
    import com.dg.gaming.api.common.util.DGUtils;
    import com.dg.gaming.client.IClient;
    import com.dg.gaming.client.TableConnection;
    import com.ericfeminella.collections.StringTokenizer;

    import flash.events.Event;
    import flash.events.EventDispatcher;
    import flash.events.IOErrorEvent;
    import flash.events.ProgressEvent;
    import flash.net.Socket;
    import flash.system.Security;
    import flash.utils.ByteArray;

    import nanoxml.XMLElement;

    public class DGConnection extends EventDispatcher implements IClient {
        private var socket:Socket;

        private var userId:int;

        private var tableId:int;

        private static var instance:DGConnection = new DGConnection();

        private var _conn:TableConnection;


        public function get connection():TableConnection {
            return _conn;
        }

        public static function getInstance():DGConnection {
            return instance;
        }

        public function connect(userId:String, tableId:String, host:String, port:String):void {
            try {
                this.userId = parseInt(userId);
            } catch (err:Error) {
                dispatchEvent(new DGEvent(DGEvent.DG_MSGTYPE_ERROR, "Please input valid UserID"));
                return;
            }
            try {
                this.tableId = parseInt(tableId);
            } catch (err:Error) {
                dispatchEvent(new DGEvent(DGEvent.DG_MSGTYPE_ERROR, "Please input valid TableID"));
                return;
            }
            var portNom:int;
            try {
                portNom = parseInt(port);
            } catch (err:Error) {
                dispatchEvent(new DGEvent(DGEvent.DG_MSGTYPE_ERROR, "Please input valid port"));
                return;
            }
            socket = new Socket();
            try {
                Security.loadPolicyFile("ClientApi-app.xml");
                socket.connect(host, portNom);
                socket.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
                socket.addEventListener(Event.CONNECT, connectedHandler);
                socket.addEventListener(ProgressEvent.SOCKET_DATA, onData);
            } catch (err:Error) {
                dispatchEvent(new DGEvent(DGEvent.DG_MSGTYPE_ERROR, err.message));
                return;
            }
        }

        private function connectedHandler(event:Event):void {
//			var conn:TableConnection=new TableConnection(socket,1,this);
            var msg:MsgConnectTable = new MsgConnectTable(tableId, userId, 1);
            var message:String = msg.flatten().toString();
            var bt:ByteArray = DGUtils.enscriptBytes(message);
//            message = DGUtils.descriptBytes(bt);
            socket.writeBytes(bt);
            socket.flush();

            //dispatchEvent(new DGEvent(DGEvent.DG_MSGTYPE_CONNECT));
        }


        private function onData(e:ProgressEvent):void {

            var bytesLoaded:int = socket.bytesAvailable;
            var bt:ByteArray = new ByteArray();
            socket.readBytes(bt);
            var str:String = DGUtils.descriptBytes(bt);
            var stTok:StringTokenizer = new StringTokenizer(str, "\n");
            while (stTok.hasMoreElements()) {
                var token:String = stTok.nextToken();
                if (token.indexOf("<") < 0)
                    continue;
                var message:XMLElement = new XMLElement();
                message.parseString(token);
                receiveGameMessage(message);
            }
        }

        public function receiveGameMessage(message:XMLElement):void {
            if (_conn != null) {
                _conn.parse(message);
                return;
            }
            var messageType:String = message.name;
            if (messageType == Msg.ERROR) {
                var commError:MsgError = new MsgError(-1, null, message);
                dispatchEvent(new DGEvent(DGEvent.DG_MSGTYPE_ERROR, DGLabels.getError(commError.getStatus())));
            } else {
                if (messageType == Msg.TABLE) {
//					socket.removeEventListener(Event.DEACTIVATE, connectedHandler);
                    var tblconnect:MsgTableConnect = new MsgTableConnect(null, null, message);
                    var table:Table = tblconnect.getTable();
                    _conn = new TableConnection(socket, userId, this);
//					socket.addEventListener(IOErrorEvent.IO_ERROR, _conn.inputDataHandler);
                    _conn.setUserName(tblconnect.getUserName());
                    _conn.setTable(table);
                    var len:int = message.chileds.length;
                    for (var i:int = 0; i < len; i++) {
                        var childMessage:XMLElement = XMLElement(message.chileds[i]);
                        if (childMessage.name == Msg.MODEL) {
                            var model:GameModel = MainPanel.mainpanel.gameModel;
                            if (model != null) {
                                model.setState(childMessage);
                                table.setModel(model);
                            }
                        }
                    }
                    trace(MainPanel.mainpanel);
                    MainPanel.mainpanel.connected();
                }
            }
        }

        public function receiveTableMessage(message:XMLElement, tableNum:String):void {
            trace(message.toString() + tableNum);
        }

        private function onIOError(evt:IOErrorEvent):void {
            dispatchEvent(new DGEvent(DGEvent.DG_MSGTYPE_ERROR, evt.text));
        }

    }
}